package drds.data_propagate.common.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.Thread.UncaughtExceptionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

public class NamedThreadFactory implements ThreadFactory {

    private static final Logger logger = LoggerFactory.getLogger(NamedThreadFactory.class);
    final static UncaughtExceptionHandler uncaughtExceptionHandler = new UncaughtExceptionHandler() {

        public void uncaughtException(Thread thread, Throwable e) {
            if (e instanceof InterruptedException
                    || (e.getCause() != null && e.getCause() instanceof InterruptedException)) {
                return;
            }

            logger.error("from " + thread.getName(), e);
        }
    };
    final private String name;
    final private boolean daemon;
    final private ThreadGroup threadGroup;
    final private AtomicInteger threadNumber = new AtomicInteger(0);

    public NamedThreadFactory(String name) {
        this(name, true);
    }

    public NamedThreadFactory(String name1, String name2) {
        this(name1 + "-" + name2, true);
    }

    public NamedThreadFactory(String name, boolean daemon) {
        this.name = name;
        this.daemon = daemon;
        SecurityManager securityManager = System.getSecurityManager();
        threadGroup = (securityManager != null) ? securityManager.getThreadGroup()
                : Thread.currentThread().getThreadGroup();
    }

    public Thread newThread(Runnable runnable) {
        Thread thread = new Thread(threadGroup, runnable, name + "-" + threadNumber.getAndIncrement(), 0);
        thread.setDaemon(daemon);
        if (thread.getPriority() != Thread.NORM_PRIORITY) {
            thread.setPriority(Thread.NORM_PRIORITY);
        }

        thread.setUncaughtExceptionHandler(uncaughtExceptionHandler);
        return thread;
    }
}
